module Language.ASTExpr.Eval where

import Language.ASTExpr.Syntax
import Data.List
import Data.Maybe

eval :: Expr -> Int
eval e = evalExp e []

evalExp :: Expr -> [(Char,Int)] -> Int
evalExp (Const _ i ) bs = i
evalExp (EVar _ x) bs = snd $ fromJust $ find (\(k,v) -> (k==x)) bs
evalExp (Neg _ e) bs   = -(evalExp e bs)
evalExp (Add _ e1 e2) bs = (evalExp e1 bs) + (evalExp e2 bs)
evalExp (Mul _ e1 e2) bs = (evalExp e1 bs) * (evalExp e2 bs)
evalExp (Let _ d e) bs = evalExp e (evalDecl d bs)

evalDecl :: Decl -> [(Char,Int)] -> [(Char,Int)]
evalDecl ((:=) _ k e) bs = (k,evalExp e bs) : bs
evalDecl (Seq _ d1 d2) bs = evalDecl d1 $ evalDecl d2 bs
evalDecl (None _) bs = bs
